package com.huadao.cart_ccs.data.task;

import android.support.annotation.IntDef;
import android.support.annotation.StringDef;

import com.huadao.cart_ccs.common.UtilHelpers;
import com.huadao.cart_ccs.greendao.GreenDaoManager;
import com.huadao.cart_ccs.greendao.entity.Operation;
import com.huadao.cart_ccs.greendao.gen.OperationDao;

import java.io.Serializable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Date;
import java.util.concurrent.ScheduledFuture;

import io.reactivex.disposables.Disposable;

public class LiquidLoopTask extends OperateTask implements Serializable {
    private static final long serialVersionUID = -9143641981887002306L;
    private int taskType;
    public static int TASK_Speed = 0;
    public static int TASK_TimeSpeed = 1;
    public static int TASK_FlowSpeed = 2;
    public static int TASK_FlowTime = 3;

    private int speed;
    private double time;//每一轮的时间
    private int flow;//每一轮的体积
    private byte direction;
    private byte modularNO;

    private ShakeTableTask shakeTableTask;//摇床任务
    private Disposable disposable;

    private ScheduledFuture scheduledFuture;

    public static final int maxAmountOneTime=30;
    //误差,预定的体积-实际称重的体积
    private int deviation;
    private int currentPeriod;
    private int totalPeriod;
    private Thread thread;
    //密度
    public final static int density=1;
    private int totalAmount;//总体积
    private int shakeTime;//摇床时间,秒

    //如果进液分为两个阶段，第一阶段结束时的flag
    private boolean isMiddleStop;

    //是否终止任务
    private boolean isTerminate;

    //初始重量，在进液或者排液前称重，用来补差
    private double initWeight;

    //灌注名称
    private String collectName;

    private boolean isSlowingDown;
    private boolean isSlowedDown;

    @LiquidType
    private int liquidType;

    public static final int Liquid_medium=1;//培养液
    public static final int Liquid_saline=2;//生理盐水
    public static final int Liquid_cryoprotectant=3;//冻存保护剂
    public static final int Liquid_cell=4;//细胞
    public static final int Liquid_viruses=5;//病毒

    @IntDef({Liquid_medium, Liquid_saline,Liquid_cryoprotectant,Liquid_cell,Liquid_viruses})
    @Retention(RetentionPolicy.SOURCE)
    public @interface LiquidType {
    }

    //是否由于报警而暂停，报警解除后要继续运行
    private boolean isPausedByAlarm;

    //是否在改变转向，改变转向需要先关闭再启动
    private boolean isChangingDirection;

    public LiquidLoopTask(int taskType, byte modularNO) {
        this.taskType = taskType;
        this.modularNO = modularNO;
    }

    public int getTaskType() {
        return taskType;
    }

    public void setTaskType(int taskType) {
        this.taskType = taskType;
    }

    public int getSpeed() {
        return speed;
    }

    public void setSpeed(int speed) {
        this.speed = speed;
    }

    public double getTime() {
        return time;
    }

    public void setTime(double time) {
        this.time = time;
    }

    public byte getDirection() {
        return direction;
    }

    public void setDirection(byte direction) {
        this.direction = direction;
    }

    public byte getModularNO() {
        return modularNO;
    }

    public void setModularNO(byte modularNO) {
        this.modularNO = modularNO;
    }

    public int getFlow() {
        return flow;
    }

    public void setFlow(int flow) {
        this.flow = flow;
    }

    public ScheduledFuture getScheduledFuture() {
        return scheduledFuture;
    }

    public void setScheduledFuture(ScheduledFuture scheduledFuture) {
        this.scheduledFuture = scheduledFuture;
    }

    //取消关闭任务
    public void cancelCloseTask() {
        //如果失败，就取消关闭任务
        if (scheduledFuture != null) {
            if (!scheduledFuture.isDone()) {
                scheduledFuture.cancel(true);
            }
            scheduledFuture = null;
        }
        thread=null;
        isPausedByAlarm=false;
        isChangingDirection=false;
        isMiddleStop=false;

    }

    //计算暂停后，剩余要运行的时间
    public double getLeftTimeAfterPause() {
        if (taskType == TASK_Speed || pauseTime == null) {
            return 0;
        }
        long runnedTime = (pauseTime.getTime() - startTime.getTime()) / 1000;
        double leftTime = time - runnedTime;
        return leftTime;
    }

    //计算暂停后，剩余要运行的流量
    public int getLeftAmountAfterPause() {
        double leftTime = getLeftTimeAfterPause();
        int leftAmount = UtilHelpers.calculateFlowBySpeedTime(speed, leftTime);
        return leftAmount;
    }

    public void pausedByAlarm() {
        state = STATE_PAUSE;
        setPauseTime(new Date());
        cancelCloseTask();
        isPausedByAlarm = true;
    }

    public boolean isPausedByAlarm() {
        return isPausedByAlarm;
    }

    public void setPausedByAlarm(boolean pausedByAlarm) {
        isPausedByAlarm = pausedByAlarm;
    }

    public boolean isChangingDirection() {
        return isChangingDirection;
    }

    public void setChangingDirection(boolean changingDirection) {
        isChangingDirection = changingDirection;
    }

    public int getDeviation() {
        return deviation;
    }

    public void setDeviation(int deviation) {
        this.deviation = deviation;
    }

    public int getCurrentPeriod() {
        return currentPeriod;
    }

    public void setCurrentPeriod(int currentPeriod) {
        this.currentPeriod = currentPeriod;
    }

    public int getTotalPeriod() {
        return totalPeriod;
    }

    public void setTotalPeriod(int totalPeriod) {
        this.totalPeriod = totalPeriod;
    }

    public Thread getThread() {
        return thread;
    }

    public void setThread(Thread thread) {
        this.thread = thread;
    }

    //获每轮的体积,根据之前称重算出的误差进行补差
    public int getAdjustAmount(){
        return flow+deviation*2;
    }

    public int getTotalAmount() {
        return totalAmount;
    }

    public void setTotalAmount(int totalAmount) {
        this.totalAmount = totalAmount;
    }

    public int getShakeTime() {
        return shakeTime;
    }

    public void setShakeTime(int shakeTime) {
        this.shakeTime = shakeTime;
    }

    public int getLiquidType() {
        return liquidType;
    }

    public void setLiquidType(@LiquidType int liquidType) {
        this.liquidType = liquidType;
    }

    public double getInitWeight() {
        return initWeight;
    }

    public void setInitWeight(double initWeight) {
        this.initWeight = initWeight;
    }

    public boolean isMiddleStop() {
        return isMiddleStop;
    }

    public void setMiddleStop(boolean middleStop) {
        isMiddleStop = middleStop;
    }

    public String getCollectName() {
        return collectName;
    }

    public void setCollectName(String collectName) {
        this.collectName = collectName;
    }

    public ShakeTableTask getShakeTableTask() {
        return shakeTableTask;
    }

    public void setShakeTableTask(ShakeTableTask shakeTableTask) {
        this.shakeTableTask = shakeTableTask;
    }

    public Disposable getDisposable() {
        return disposable;
    }

    public void setDisposable(Disposable disposable) {
        this.disposable = disposable;
    }

    public boolean isTerminate() {
        return isTerminate;
    }

    public void setTerminate(boolean terminate) {
        isTerminate = terminate;
    }

    public boolean isSlowingDown() {
        return isSlowingDown;
    }

    public void setSlowingDown(boolean slowingDown) {
        isSlowingDown = slowingDown;
    }

    public boolean isSlowedDown() {
        return isSlowedDown;
    }

    public void setSlowedDown(boolean slowedDown) {
        isSlowedDown = slowedDown;
    }
}
